package com.example.myforum.service.impl;

import com.example.myforum.common.AppResult;
import com.example.myforum.common.ResultCode;
import com.example.myforum.dao.UserMapper;
import com.example.myforum.exception.ApplicationException;
import com.example.myforum.model.Board;
import com.example.myforum.model.UpdateUser;
import com.example.myforum.model.User;
import com.example.myforum.service.IUserService;
import com.example.myforum.utils.MD5Utils;
import com.example.myforum.utils.RegexUtil;
import com.example.myforum.utils.UUIDUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;

@Service
@Slf4j
public class IUserServiceImpl implements IUserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public void createNormalUser(User user) {
        if (user == null) {
            throw new ApplicationException((AppResult.fail(ResultCode.ERROR_IS_NULL)));
        }
        // 从数据库中查询当前用户是否存在
        User existUser = userMapper.selectByUserName(user.getUsername());
        if (existUser != null) {
            //打印日志：输出已经存在的用户
            log.info(ResultCode.AILED_USER_EXISTS.toString() + "username = "
                    + user.getUsername());
            //用户已经存在了，没有办法注册了，抛出异常
            throw new ApplicationException((AppResult.fail(ResultCode.AILED_USER_EXISTS)));
        }
        //插入用户，除了注册时用户输入的几个参数，其他全用默认值
        if (user.getGender() == null) {
            user.setGender((byte) 2);
        }
        user.setIsAdmin((byte) 0);
        user.setAvatarUrl(null);
        user.setArticleCount(0);
        user.setState((byte) 0);
        Date date = new Date();
        user.setCreateTime(date);
        user.setUpdateTime(date);
        int row = userMapper.insertSelective(user);
        if (row != 1) {
            log.info(ResultCode.FAILED_CREATE.toString() + "username = " +
                    user.getUsername());
            // 抛出异常
            throw new
                    ApplicationException(AppResult.fail(ResultCode.FAILED_CREATE));
        } else {
            log.info("创建普通用户成功: " + "username = " + user.getUsername());
        }
    }

    @Override
    public User login(String username, String password) {
        /**
         * 一直有个疑问 这里的username,password 是controller 传来，
         * 验证空不空，非法不非法 controller 哪里已经校验了
         *
         * 1.先通过username 去查询数据库这个用户是否存在
         *
         */
        User user = userMapper.selectByUserName(username);
        if (user == null) {
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_LOGIN));
        }
        String md5Salt = MD5Utils.md5Salt(password, user.getSalt());
        if (!md5Salt.equals(user.getPassword())) {
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_LOGIN));
        }
        user.setPassword("");
        user.setSalt("");
        return user;
    }

    @Override
    public int modifyInfo(User user) {
        if (user == null || user.getId() <= 0 || user.getId() == null) {
            log.warn("modifyInfo:" + "修改错误 id不合法");
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        //2.检验数据库中是否存在这个要修改的用户
        User existsUser = userMapper.selectByPrimaryKey(user.getId());
        if (existsUser == null) {
            log.warn("modifyInfo:" + "修改错误 用户不存在无法修改");
            throw new ApplicationException(AppResult.fail("修改错误 用户不存在无法修改"));
        }
        //3.这里要检验手机号和邮箱是否合法
        if (user.getEmail() != null && !RegexUtil.checkMail(user.getEmail())) {
            log.warn("modifyInfo:" + "修改错误 邮箱不合法");
            throw new ApplicationException(AppResult.fail("修改错误 邮箱不合法"));
        }
        if (user.getPhoneNumber() != null && !RegexUtil.checkMobile(user.getPhoneNumber())) {
            log.warn("modifyInfo:" + "修改错误 手机号不合法");
            throw new ApplicationException(AppResult.fail("修改错误 手机号不合法"));
        }
        //4.使用动态sql动态修改
        int ret = userMapper.updateByPrimaryKeySelective(user);
        if (ret != 1) {
            log.warn("modifyInfo:" + "数据库update失败");
        }
        return ret;
    }

    @Override
    public User getUserInfo(Long id) {
        return userMapper.selectByPrimaryKey(id);
    }

    @Override
    public void modifyPwd(UpdateUser updateUser) {
        //1.检验一下这个修改的用户是否存在
        User existedUser = userMapper.selectByPrimaryKey(updateUser.getId());
        if (existedUser == null) {
            log.warn("modifyPwd" + "用户不存在");
            throw new ApplicationException(AppResult.fail("用户不存在"));
        }
        //2.检验一下old密码是否正确
        String oldPasword = MD5Utils.md5Salt(updateUser.getOldPassword(), existedUser.getSalt());
        if (!oldPasword.equals(existedUser.getPassword())) {
            log.warn("modifyPwd" + "原密码错误");
            throw new ApplicationException(AppResult.fail("原密码错误"));
        }
        //3.开始生成盐值，新密码。保存到数据库
        String newSalt = UUIDUtils.getUUID_32();
        String newPassword = MD5Utils.md5Salt(updateUser.getNewPassword(), newSalt);
        User newUser = new User();
        newUser.setId(updateUser.getId());
        newUser.setUpdateTime(new Date());
        newUser.setPassword(newPassword);
        newUser.setSalt(newSalt);
        int ret = userMapper.updateByPrimaryKeySelective(newUser);
        if (ret != 1) {
            log.warn("modifyPwd" + "修改密码错误，update数据库失败");
            throw new ApplicationException(AppResult.fail("修改密码失败"));
        }
    }

    @Override
    public void addOneArticleCountById(Long id) {
        if (id == null || id <= 0) {
            // 打印⽇志
            log.warn("addOneArticleCountById: id非法");
            // 抛出异常
            throw new ApplicationException(AppResult.fail("addOneArticleCountById: id非法"));
        }
        // 查询⽤⼾信息
        User user = userMapper.selectByPrimaryKey(id);
        if (user == null) {
            // 打印⽇志
            log.warn(ResultCode.ERROR_IS_NULL.toString() + ", user id = " + id);
            // 抛出异常
            throw new ApplicationException(AppResult.fail(ResultCode.ERROR_IS_NULL));
        }
        // 更新⽤⼾的发帖数量
        User updateUser = new User();
        updateUser.setId(user.getId());
        updateUser.setArticleCount(user.getArticleCount() + 1);
        // 更新数据库
        int row = userMapper.updateByPrimaryKeySelective(updateUser);
        if (row != 1) {
            log.warn(ResultCode.FAILED.toString() + ", 受影响的⾏数不等于 1 .");
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED));
        }

    }

    @Override
    public User selectById(Long Id) {
        return userMapper.selectByPrimaryKey(Id);
    }

    @Override
    public void subOneArticleCountById(Long id) {
        if (id == null || id <= 0) {
            // 打印⽇志
            log.warn("subOneArticleCountById:id非法-" + id);
            // 抛出异常
            throw new ApplicationException("subOneArticleCountById:id非法-" + id);
        }
        // 查询⽤⼾信息
        User user = userMapper.selectByPrimaryKey(id);
        if (user == null) {
            // 打印⽇志
            log.warn(ResultCode.ERROR_IS_NULL.toString() + ", user id = " + id);
            // 抛出异常
            throw new
                    ApplicationException(AppResult.fail(ResultCode.ERROR_IS_NULL));
        }
        // 更新⽤⼾的发帖数量
        User updateUser = new User();
        updateUser.setId(user.getId());
        updateUser.setArticleCount(user.getArticleCount() - 1);
        // 判断减1之后，⽤⼾的发帖数是否⼩于0
        if (updateUser.getArticleCount() < 0) {
            // 如果⼩于0，则设置为0
            updateUser.setArticleCount(0);
        }
        // 更新数据库
        int row = userMapper.updateByPrimaryKeySelective(updateUser);
        if (row != 1) {
            log.warn(ResultCode.FAILED.toString() + ", 受影响的⾏数不等于 1 .");
            throw new ApplicationException(AppResult.fail(ResultCode.FAILED));
        }
    }
}
